package com.twu.biblioteca;

public class LibraryManager {

    private final String NEW_LINE = "\n";
    private final String LINE_DIVIDER = "================";
    private final String DETAILS_SEPARATOR = ", ";
    private String display;
    private Library library;
    private UserManager userManager;
    private User currentUser = null;

    public LibraryManager() {
        library = new Library();
        this.display = TextConstants.WELCOME_MESSAGE + NEW_LINE + NEW_LINE + getMenu();
    }

    public LibraryManager setLibrary(Library library) {
        this.library = library;

        return this;
    }

    public String getDisplay() {
        return display;
    }

    public LibraryManager select(Option option) {
        return select(option, null, null);
    }

    public LibraryManager select(Option option, Object arg1) {
        return select(option, arg1, null);
    }

    public LibraryManager select(Option option, Object arg1, Object arg2) {

        if (notAuthorized(option)) {
            this.display = TextConstants.LOGIN_REQUIRED;
            return this;
        }

        switch (option) {
            case ADD_BOOK:
                this.display = addBook(arg1.toString(), arg2.toString());
                break;

            case VIEW_ALL_BOOKS:
                this.display = library.getAvailableBookShelf().toString();
                break;

            case VIEW_ALL_MOVIES:
                this.display = library.getAvailableMovieShelf().toString();
                break;

            case RESERVE_BOOK:
                this.display = reserveBook(arg1.toString());
                break;

            case MEMBERSHIP_DETAILS:
                this.display = getMembershipDetails();
                break;

            case LOGIN:
                this.display = login(arg1.toString(), arg2.toString());
                break;

            case SHOW_MENU:
                this.display = getMenu();
                break;

            case INVALID:
                this.display = TextConstants.UNKNOWN_OPTION;
                break;
        }

        return this;
    }

    public boolean notAuthorized(Option option) {
        return !isLoggedIn() && userManager != null && !option.isPubliclyVisible();
    }

    private String getMembershipDetails() {
        if (isLoggedIn()) {
            return currentUser.getName() + DETAILS_SEPARATOR
                    + currentUser.getEmail() + DETAILS_SEPARATOR
                    + currentUser.getPhone();
        }

        return TextConstants.MEMBERSHIP_DETAILS_RESPONSE;
    }

    private String login(String username, String password) {
        if (userManager != null && userManager.auth(username, password)) {
            currentUser = userManager.get(new LibraryNumber(username));
            return TextConstants.LOGIN_SUCCESSFUL;
        }
        return TextConstants.LOGIN_FAILED;
    }

    private String addBook(String title, String author) {
        library.addBook(new Book(title, author));

        return TextConstants.BOOK_ADDED_SUCCESSFULLY;
    }

    private String reserveBook(String title) {
        Book book = library.getBookWithTitle(title);

        if (book != null && !library.bookIsReserved(book)) {
            library.reserveBook(book);
            return TextConstants.RESERVED_SUCCESSFULLY;
        }

        return TextConstants.SELECTION_UNAVAILABLE;
    }

    public String getMenu() {
        return TextConstants.SELECT_OPTION + NEW_LINE +
                LINE_DIVIDER + NEW_LINE +
                Option.ADD_BOOK.asMenuOption() + NEW_LINE +
                Option.VIEW_ALL_BOOKS.asMenuOption() + NEW_LINE +
                Option.VIEW_ALL_MOVIES.asMenuOption() + NEW_LINE +
                Option.RESERVE_BOOK.asMenuOption() + NEW_LINE +
                Option.MEMBERSHIP_DETAILS.asMenuOption() + NEW_LINE +
                Option.LOGIN.asMenuOption() + NEW_LINE +
                Option.SHOW_MENU.asMenuOption() + NEW_LINE +
                Option.EXIT.asMenuOption() + NEW_LINE ;
    }

    public Library getLibrary() {
        return library;
    }

    public LibraryManager setDisplay(String display) {
        this.display = display;
        return this;
    }

    public LibraryManager setUserManager(UserManager userManager) {
        this.userManager = userManager;
        return this;
    }

    public boolean isLoggedIn() {
        return currentUser != null;
    }

    public LibraryManager setCurrentUser(User user) {
        this.currentUser = user;
        return this;
    }
}
